SPDX-FileCopyrightText: 2020 Jeanne Mujawamariya & Sara Paolitto SPDX-FileCopyrightText: 2024 AlICe laboratory https://alicelab.be
SPDX-License-Identifier: GPL-3.0-or-later
import bpy
from random import randintget object of given
def _get_object(name): result = None
for obj in bpy.data.objects:
if obj.name.lower() == name.lower():
result = obj
break
return resultreturns the corners of the bounding box of an object in world coordinates
def get_BoundBox(object_name): from mathutils import Vector
bpy.context.view_layer.update()
ob = _get_object(object_name)get list of vertices world coordinates
bbox_corners = [ob.matrix_world @ Vector(corner) for corner in ob.bound_box]
return bbox_cornersCheck Collision of 2 Bounding Boxes box1 & box2 must be lists of Vectors, containg the edges of the bounding boxes
def check_Collision(box1, box2): print("[START]\tCOLLISION CHECK")
x_max = max([e[0] for e in box1])
x_min = min([e[0] for e in box1])
y_max = max([e[1] for e in box1])
y_min = min([e[1] for e in box1])
z_max = max([e[2] for e in box1])
z_min = min([e[2] for e in box1])
print("[INFO] Box1 min %.2f, %.2f, %.2f" % (x_min, y_min, z_min))
print("[INFO] Box1 max %.2f, %.2f, %.2f" % (x_max, y_max, z_max))
x_max2 = max([e[0] for e in box2])
x_min2 = min([e[0] for e in box2])
y_max2 = max([e[1] for e in box2])
y_min2 = min([e[1] for e in box2])
z_max2 = max([e[2] for e in box2])
z_min2 = min([e[2] for e in box2])
print("[INFO] Box2 min %.2f, %.2f, %.2f" % (x_min2, y_min2, z_min2))
print("[INFO] Box2 max %.2f, %.2f, %.2f" % (x_max2, y_max2, z_max2))Check max and min values of coordinates Here, values must be inferior or equal
isColliding = (
(
(x_max >= x_min2 and x_max <= x_max2)
or (x_min <= x_max2 and x_min >= x_min2)
or (x_max2 <= x_max and x_min2 >= x_min)
or (x_max <= x_max2 and x_min >= x_min2)
)
and (
(y_max >= y_min2 and y_max <= y_max2)
or (y_min <= y_max2 and y_min >= y_min2)
or (y_max2 <= y_max and y_min2 >= y_min)
or (y_max <= y_max2 and y_min >= y_min2)
)
and (
(z_max >= z_min2 and z_max <= z_max2)
or (z_min <= z_max2 and z_min >= z_min2)
or (z_max2 <= z_max and z_min2 >= z_min)
or (z_max <= z_max2 and z_min >= z_min2)
)
)
print("[END]\tCOLLISION CHECK")
return isCollidingdef make_cube(coord, vector):
bpy.ops.mesh.primitive_cube_add(location=coord)
bpy.ops.transform.resize(value=vector)
cube = bpy.context.selected_objects[0]
return cubedef structure(n):initial cube
x, y, z = (randint(0, 10), randint(0, 10), randint(0, 10))
cube1 = make_cube((x, y, z), (0.5, 0.5, 0.5))
cube_list = [cube1]
while len(cube_list) < n:adding a cube
collision = False
while not collision:
x, y, z = (randint(0, 10), randint(0, 10), randint(0, 10))
cube2 = make_cube((x, y, z), (1.5, 1.5, 1.5))
for cube in cube_list:
collision = check_Collision(
get_BoundBox(cube.name), get_BoundBox(cube2.name)
)
if not collision:
bpy.ops.object.delete(use_global=False)
else:
cube_list.append(cube2)
return cube_listdef join_objects(list):
bpy.ops.object.select_all(action="DESELECT")
for obj in list:
obj.select_set(True)
bpy.ops.object.join()
new_structure = bpy.context.selected_objects[0]
return new_structuredef rotation(object, rotation):
bpy.ops.transform.rotate(value=rotation, orient_axis="Z")
structure1 = structure(10)
obj = join_objects(structure1)
obj.name = "inside smallcubes"
rotation(obj, -0.9)
structure2 = structure(3)
obj2 = join_objects(structure2)
obj2.name = "2 small cubes"
rotation(obj, -0.19)def structure(n):initial cube
x, y, z = (randint(0, 5), randint(0, 5), randint(0, 5))
cube1 = make_cube((x, y, z), (1.0, 1.0, 1.0))
cube_list = [cube1]
while len(cube_list) < n:adding a cube
collision = False
while not collision:
x, y, z = (randint(0, 10), randint(0, 10), randint(0, 10))
cube2 = make_cube((x, y, z), (1, 1, 1))
for cube in cube_list:
collision = check_Collision(
get_BoundBox(cube.name), get_BoundBox(cube2.name)
)
if not collision:
bpy.ops.object.delete(use_global=False)
else:
cube_list.append(cube2)
return cube_listdef join_objects(list):
bpy.ops.object.select_all(action="DESELECT")
for obj in list:
obj.select_set(True)
bpy.ops.object.join()
new_structure = bpy.context.selected_objects[0]
return new_structuredef rotation(object, rotation):
bpy.ops.transform.rotate(value=rotation, orient_axis="Y")
structure1 = structure(3)
obj = join_objects(structure1)
obj.name = "inside 2 smallcubes"
rotation(obj, -0.50)
structure2 = structure(2)
obj2 = join_objects(structure2)
obj2.name = "2 small cubes"to create the outside big cube
def cube10():
bpy.ops.mesh.primitive_cube_add(size=10, location=(5, 5, 5))
cube10()